---
title: Reasoning
---

import { Steps, Step } from "fumadocs-ui/components/steps";
import { InstallCommand } from "@/components/docs/install-command";

## Overview

The Reasoning component displays AI reasoning or thinking messages in a collapsible UI. Consecutive reasoning message parts are automatically grouped together with smooth animations and a shimmer effect while streaming.

## Getting Started

<Steps>
  <Step>

### Add `reasoning`

<InstallCommand shadcn={["reasoning"]} />

This adds a `/components/assistant-ui/reasoning.tsx` file to your project, which you can adjust as needed.

  </Step>
  <Step>

### Use in your application

Pass the `Reasoning` and `ReasoningGroup` components to the `MessagePrimitive.Parts` component:

```tsx title="/app/components/assistant-ui/thread.tsx" {2,10-11}
import { MessagePrimitive } from "@assistant-ui/react";
import { Reasoning, ReasoningGroup } from "@/components/assistant-ui/reasoning";

const AssistantMessage: FC = () => {
  return (
    <MessagePrimitive.Root className="...">
      <div className="...">
        <MessagePrimitive.Parts 
          components={{ 
            Reasoning: Reasoning,
            ReasoningGroup: ReasoningGroup
          }} 
        />
      </div>
      <AssistantActionBar />

      <BranchPicker className="..." />
    </MessagePrimitive.Root>
  );
};
```

  </Step>
</Steps>

## How It Works

The component consists of two parts:

1. **Reasoning**: Renders individual reasoning message part content
2. **ReasoningGroup**: Wraps consecutive reasoning parts in a collapsible container

Consecutive reasoning parts are automatically grouped together by the `ReasoningGroup` component, similar to how `ToolGroup` handles tool calls.

### Reasoning

The Reasoning component doesn't accept additional props—it renders the reasoning text content with markdown support.

## Examples

### Basic Usage

```tsx title="/app/components/assistant-ui/thread.tsx"
<MessagePrimitive.Parts 
  components={{ 
    Reasoning,
    ReasoningGroup 
  }} 
/>
```

### Custom Styling

Since the component is copied to your project, you can customize it directly by modifying the `reasoning.tsx` file. The internal components (`ReasoningRoot`, `ReasoningTrigger`, `ReasoningContent`, `ReasoningText`) accept `className` props for styling:

```tsx title="/components/assistant-ui/reasoning.tsx"
const ReasoningGroupImpl: ReasoningGroupComponent = ({
  // ... existing code ...
  return (
    <ReasoningRoot className="rounded-lg border bg-muted/50 p-4">
      <ReasoningTrigger 
        active={isReasoningStreaming} 
        className="font-semibold text-foreground"
      />
      <ReasoningContent 
        aria-busy={isReasoningStreaming}
        className="mt-2"
      >
        <ReasoningText className="text-base">{children}</ReasoningText>
      </ReasoningContent>
    </ReasoningRoot>
  );
};
```

You can also customize the individual internal components:

```tsx title="/components/assistant-ui/reasoning.tsx"
const ReasoningRoot: FC<PropsWithChildren<{ className?: string }>> = ({ 
  // ... existing code ...
  return (
    <Collapsible
      // ...
      className={cn("aui-reasoning-root mb-4 w-full rounded-lg border bg-muted/50 p-4", className)}
      // ...
    >
      {children}
    </Collapsible>
  );
};

const ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({
  // ... existing code ...
  <CollapsibleTrigger
    className={cn(
      "aui-reasoning-trigger group/trigger -mb-2 flex max-w-[75%] items-center gap-2 py-2 text-sm font-semibold text-foreground transition-colors hover:text-foreground",
      className,
    )}
  >
    {/* ... existing content ... */}
  </CollapsibleTrigger>
);
```

## Technical Details

### Scroll Lock

The component uses the `useScrollLock` hook (exported from `@assistant-ui/react`) to prevent page jumps when collapsing the reasoning section. This maintains the scroll position during the collapse animation.

### Animation Timing

The component uses CSS custom properties for animation timing:
- `--animation-duration`: Controls expand/collapse animation (default: 200ms)
- `--shimmer-duration`: Controls the shimmer effect speed (default: 1000ms)

These can be customized by modifying the CSS variables in your component.

## Related Components

- [ToolGroup](/docs/ui/ToolGroup) - Similar grouping pattern for tool calls
- [PartGrouping](/docs/ui/PartGrouping) - Experimental API for grouping message parts
